package
{
	import classes.RecodeEvent;
	import classes.RecordManager;
	import classes.Waveform;
	
	import fl.containers.ScrollPane;
	import fl.controls.Button;
	import fl.controls.CheckBox;
	
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.external.ExternalInterface;
	import flash.geom.Utils3D;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundTransform;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.net.URLRequestHeader;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	import flash.utils.ByteArray;
	import flash.utils.Timer;
	
	import org.bytearray.micrecorder.encoder.WaveEncoder;
	
	[SWF( width="620", height="200", frameRate="40", backgroundColor="#ffffff" )]
	public class Main extends Sprite
	{
		private var _skin:SpeakingSkin;
		private var _recordManager:RecordManager;
		private var _btnRecordAndStop:MovieClip;
		private var _btnPlay:MovieClip;
		private var _btnYourSnd:MovieClip;
//		private var _btnSubmit:Sprite;
		private var _chkShadow:Object;
		private var _waveContainer:MovieClip;
		private var _scroll:ScrollPane;
		private var _wave:MovieClip; 
		private var _alert:MovieClip;
		private var _btnAlertConfirm:Button;
		private var _nativeWave:Sprite;
		private var _yourWave:Sprite; 
		private var _timeLine:Sprite;
		private var _playHead:Sprite;
		private var _userId:String = "";
		private var _nativeSndId:String = "";
		private var _nativeSndUrl:String = "";
		private var _naviveSnd:Sound;
		private var _naviveSndCh:SoundChannel;
		private var _waveform:Waveform;
		private var _playing:Boolean = false;
		private var _playingType:String = "";
		private var _playTimer:Timer;
		private var _dictationSelect:String;
		private var _httpDictationSelect:URLLoader;
		private var _splitStartArray:Array = [];
		private var _splitEndArray:Array = [];
		private var _splitTotalWidth:Number;
		private var _startSec:Number = 0;
		private var _endSec:Number = 0;
		private var _urlLoader:URLLoader;
		private var _iSheet:int;
		private var _iNum:int;
		private var _iPublish:int;
		private var _countSound:CountSound;
		private var _startSound:StartSound;
		private var _owner:String;
		private var _iCP:String;
		public function Main(){
			init();
			setSkin();
			addEvents();
			loadMark();
		}
		private function init():void{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			_recordManager = new RecordManager();
			_userId = loaderInfo.parameters.userID || "chunk";
			_iSheet = loaderInfo.parameters.iSheet || 0;
			_iNum = loaderInfo.parameters.iNum || 0;
			_iPublish = loaderInfo.parameters.iPublish || 0;
			_dictationSelect = loaderInfo.parameters.dictationSelect || "http://www.chunkeng.co.kr/ap_shop/sp_dictation/dictationSelect.php";
			var nativeSndData:String = loaderInfo.parameters.dictationFiles || "224,http://www.chunkeng.co.kr/ap_shop/sp_dictation/songs/TrackNo11.mp3";
			_iCP = loaderInfo.parameters.iCP || "0";
			var nativeSndDataArr:Array = nativeSndData.split( "," );
			if( nativeSndDataArr.length != 2 ) return;
			_nativeSndId = nativeSndDataArr[ 0 ];
			_nativeSndUrl = nativeSndDataArr[ 1 ];
			_playTimer = new Timer( 10 );
			_httpDictationSelect = new URLLoader(); 
			_urlLoader = new URLLoader();
			
			_countSound = new CountSound();
			_startSound = new StartSound();
		}
		private function setSkin():void{
			_skin = new SpeakingSkin();
			_skin.count.visible = false;
			_btnRecordAndStop = _skin.btnRecordAndPause;
			_btnPlay = _skin.btnPlay;
//			_btnSubmit = _skin.btnSubmit;
			_btnYourSnd = _skin.btnYourSnd;
			_chkShadow = _skin.chkShadow as CheckBox;
			_waveContainer = _skin.waveContainer;
			_wave = _skin.waveContainer.wave;
			_nativeWave = _wave.waveNative;
			_yourWave = _wave.waveYour;
			_timeLine = _wave.timeline;
			_playHead = _wave.playHead;
			_scroll = _waveContainer.scroll as ScrollPane;
			_scroll.setSize( _wave.width, 137 );
			_scroll.source = _wave;
			_waveform = new Waveform( _nativeWave, _yourWave, _timeLine );
//			_alert = _skin.alert;
//			_btnAlertConfirm = _alert.confirm;
//			_alert.visible=false;
			_btnYourSnd.gotoAndStop( 3 );
			_btnYourSnd.mouseEnabled = false;
			_btnYourSnd.enabled = false;
			addChild( _skin );
		}
		private function addEvents():void{
			_recordManager.addEventListener( "count", recordCountHandler );
			_recordManager.addEventListener( "start", recordStartHandler );
			_recordManager.addEventListener( "end", recordEndHandler );
			_recordManager.addEventListener( RecodeEvent.PLAYING, recoedSndPlayHandler );
			_recordManager.addEventListener( "your_snd_complete", yourSndCompleteHandler );
			_btnRecordAndStop.buttonMode = _btnPlay.buttonMode = true;
			_btnRecordAndStop.addEventListener( MouseEvent.CLICK, clickRecordStartHandler);
			_btnPlay.addEventListener( MouseEvent.CLICK, clickPlaytHandler );
			_btnYourSnd.addEventListener( MouseEvent.CLICK, clickYourSndHandler );
			_playTimer.addEventListener( TimerEvent.TIMER, checkNativeSndPosition );
			_httpDictationSelect.addEventListener( Event.COMPLETE, getMarkDataHandler ); 
//			_btnSubmit.addEventListener( MouseEvent.CLICK, submitHandler );
			_urlLoader.addEventListener( Event.COMPLETE, uploadHandler );
//			_btnAlertConfirm.addEventListener( MouseEvent.CLICK, function( event:MouseEvent ):void{ _alert.visible=false;});
		}
		private function loadMark():void{
			_httpDictationSelect.load( new URLRequest( _dictationSelect + "?userID="+_userId +"&fileID="+_nativeSndId ))
		}
		private function loadSound( url:String ):void{
			_naviveSnd = new Sound();	
			_naviveSnd.addEventListener(Event.COMPLETE, soundFileCompleteHandler );
			var soundTrans:SoundTransform = new SoundTransform();
			soundTrans.volume = 0.3;
			if( url.indexOf( "songs/" ) == -1  ) url = "songs/"+_iCP +"/"+url;
			_naviveSnd.load(new URLRequest( url ) );
		}
		private function playNativeSnd():void{
			_btnPlay.gotoAndStop( 2 );
			_naviveSndCh = _naviveSnd.play( _startSec*1000 );
			_wave.setChildIndex( _yourWave, 0 );
			_playTimer.start()
		}
		private function stopNativeSnd():void{
			_btnPlay.gotoAndStop( 1 );	
			if( _naviveSndCh ) _naviveSndCh.stop();
			_playTimer.stop();
		}
		private function checkNativeSndPosition( event:TimerEvent ):void{
			var startMilSec:Number = (_startSec*1000)
			var endMilSec:Number = (_endSec*1000)
			_playHead.x = ( _waveform.naitveMaxWidth - 0)/( endMilSec-startMilSec )*( _naviveSndCh.position-startMilSec )+0;
			if( _naviveSndCh.position >= _endSec*1000 ){
				_playing = false;
				_btnPlay.gotoAndStop( 1 );
				_playTimer.stop();
				_naviveSndCh.stop();
				if( _naviveSndCh ) _naviveSndCh.stop();
				ExternalInterface.call( "console.log", _chkShadow.selected + " / " + _owner +" / " +  _hasRecord ); 
				if( _chkShadow.selected && _owner == "n" && _hasRecord ){
					clickYourSndHandler( null );
				}
			}
		}
		private function submitHandler( event:MouseEvent ):void{ 
			if( _recordManager.src == null || _recordManager.src.length == 0 ) return;
			var waveByte:ByteArray = new WaveEncoder().encode( _recordManager.src, 2, 16, 44100/2 );
			var req:URLRequest = new URLRequest( "./speaking_save.php" ); 
			var parameters:URLVariables = new URLVariables();
			parameters.iSheet = _iSheet; 
			parameters.iNum = _iNum;
			parameters.iPublish = _iPublish;
			
			req.method = URLRequestMethod.POST;  
			req.contentType = 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary();
			req.data = UploadPostHelper.getPostData( new Date().time+".wav", waveByte, parameters);
			req.requestHeaders.push( new URLRequestHeader( 'Cache-Control', 'no-cache' ) );
			_urlLoader.dataFormat = URLLoaderDataFormat.BINARY; 
			try
			{
				_urlLoader.load( req );	
			} 
			catch(error:Error) 
			{
				ExternalInterface.call( "console.log", error );
			}
			
		} 
		private function uploadHandler( event:Event ):void{
			ExternalInterface.call( "console.log", _urlLoader.data );
			ExternalInterface.call( "submitComplete",  _iSheet, _iNum );
//			_alert.visible=true;
		}
		private function soundFileCompleteHandler( event:Event ):void{
			var sndLength:Number = _naviveSnd.length / 1000;
			var sndBytes:Number = ( _naviveSnd.length/1000) *44100
			var startPos:Number = ( sndBytes-0 ) / ( _splitTotalWidth-0 ) * ( _splitStartArray[ 0 ]);
			var endPos:Number = ( sndBytes-0 ) / ( _splitTotalWidth-0 ) * ( _splitEndArray[ 0 ]);
			_startSec = ( sndLength-0 ) / ( _splitTotalWidth-0 ) * ( _splitStartArray[ 0 ]);
			_endSec = ( sndLength-0 ) / ( _splitTotalWidth-0 ) * ( _splitEndArray[ 0 ]);
			_waveform.drawNative( _naviveSnd, startPos, endPos-startPos );
			/*Util.LOG( _splitTotalWidth + " / " + _splitStartArray[ 0 ] + " / " + _splitEndArray[ 0 ]);
			Util.LOG( sndBytes + " / " + startPos + " / " + endPos );
			Util.LOG( sndLength + " / " + _startSec + " / " + _endSec );*/
			_waveform.drawtimeLine( _startSec, _startSec ); 
			_scroll.refreshPane();
		}
		private function clickRecordStartHandler( evnet:MouseEvent ):void{
			if( _recordManager.recording ){
				_skin.btnRecordAndPause.gotoAndStop(1);
				_recordManager.end();
				_btnYourSnd.gotoAndStop( 1 );
				_btnYourSnd.mouseEnabled = true;
				_btnYourSnd.enabled = true;
				_scroll.refreshPane();
				
				// 제출하기
				if( _recordManager.src == null || _recordManager.src.length == 0 ) return;
				var waveByte:ByteArray = new WaveEncoder().encode( _recordManager.src, 2, 16, 44100/2 );
				var req:URLRequest = new URLRequest( "./speaking_save.php" ); 
				var parameters:URLVariables = new URLVariables();
				parameters.iSheet = _iSheet; 
				parameters.iNum = _iNum;
				parameters.iPublish = _iPublish;
				
				req.method = URLRequestMethod.POST;  
				req.contentType = 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary();
				req.data = UploadPostHelper.getPostData( new Date().time+".wav", waveByte, parameters);
				req.requestHeaders.push( new URLRequestHeader( 'Cache-Control', 'no-cache' ) );
				_urlLoader.dataFormat = URLLoaderDataFormat.BINARY; 
				try
				{
					_urlLoader.load( req );	
				} 
				catch(error:Error) 
				{
					ExternalInterface.call( "console.log", error );
				}
			}else{
				_skin.btnRecordAndPause.gotoAndStop(2);
				_waveform.clearYour();
				_recordManager.start();	
				_skin.count.visible = true;
				stopNativeSnd();
			}
		}
		private function clickPlaytHandler( evnet:MouseEvent ):void{
			if( !_naviveSnd ) return;
			if( _naviveSndCh ) _naviveSndCh.stop();
			if( evnet ) _owner = "n";
			_playing = !_playing;
			if( _playing ) {
				playNativeSnd();
				_nativeWave.alpha = 1;
				_yourWave.alpha = 0.2;
			}else{
				stopNativeSnd();
			}
		}
		private function clickYourSndHandler( evnet:MouseEvent ):void{
			if( evnet ) _owner = "y";
			_playing = !_playing;
			if( _playing ) {
				stopNativeSnd();
				_wave.setChildIndex( _nativeWave, 0 );
				_nativeWave.alpha = 0.2;
				_yourWave.alpha = 1;
				_recordManager.play();
				_btnYourSnd.gotoAndStop( 2 );
			}else{
				_recordManager.stop();
				_btnYourSnd.gotoAndStop( 1 );
			}
		} 
		private function recordCountHandler( event:Event ):void{
			_skin.count.gotoAndStop( _recordManager.count );
			
			if(  _recordManager.count == 1 ){
				// 볼륨 줄임
				var trans:SoundTransform = new SoundTransform(0.1, 0);
				_startSound.play(0, 1, trans);
			}
		}
		private function recordStartHandler( event:Event ):void{
			//_skin.count.visible = false;
		}
		private var _hasRecord:Boolean = false;
		private function recordEndHandler( event:Event ):void{
			_hasRecord = true;
			_waveform.drawYour( _recordManager.src );
			_yourWave.alpha = 1;
			_skin.count.visible = false;
		} 
		private function recoedSndPlayHandler( event:RecodeEvent ):void{
			_playHead.x = ( (_waveform.yourMaxWidth - 25) - 0 )/( event.totalByteLength - 0 )*( event.playedByteLength -0)+( 0 );
//			ExternalInterface.call( "console.log",event.playedByteLength + " / " + _playHead.x );
		}
		private function yourSndCompleteHandler( event:Event ):void{
			_playHead.x = _waveform.yourMaxWidth;
			_btnYourSnd.gotoAndStop( 1 );
			_playing = false;
			if( _chkShadow.selected && _owner == "y"){
				clickPlaytHandler( null );
			}
		}
		private function getMarkDataHandler( event:Event ):void{
			var selectResult:String = event.target.data.toString();
			var sValue:Array = selectResult.split(",");
			var index:int = ( ( _iNum -1 ) * 2)+2;
			_splitTotalWidth = Number( sValue[ 0 ] );
			_splitStartArray.push(sValue[index]);
			_splitEndArray.push(sValue[index+1]);
			Util.LOG( sValue[index] + " / " + sValue[index+1])
			loadSound( _nativeSndUrl );
		}
	}
}